JavaScript中的數據都是有型別的,共有八種型別:
let n = 123;
n = 12.345;
number類型包含整數和小數,數字類型可以有很多操作,加減乘除等等。
除了一般的常規數字之外,也包含了特殊數值(special numeric value) --- Infinity,-Infinity和NaN。
我們可以透過除0得到
alert( 1 / 0 ); // Infinity
或是直接在代碼中使用:
alert( Infinity ); // Infinity
alert( "some string" / 2 ); // NaN
對NaN進行任何操作都會返回NaN的。
在JavaScript中繼算是相對安全的,例如除以0或是將非數字字串視為數字等,都不會因此報錯,最壞的結果就是得到一個NaN。
在JavaScript中,number類型無法表示大於2的53次方減一(即9007199254740991)或是小於-(2的53次方減一)的整數,在大多數情況這其實已經足夠,但如果必要時需要這個區間以外的整數時,可以將n附加在數字後面取得BigInt類型的值。
// 尾部的"n"表示這是一個BigInt類型
const bigInt = 1234567890123456789012345678901234567890n;
字串必須包含在引號內:
let str = "Hello";
let str2 = 'Single quotes are ok too';
let phrase = `can embed another ${str}`;
單引號跟雙引號基本上是沒什麼差別的,而反引號允許我們將變數或是表達式包裝在引號中的${}:
let name = "David";
// 加入一个變數
alert( `Hello, ${name}!` ); // Hello, David!
// 加入一個表達式
alert( `the result is ${1 + 2}` ); // the result is 3
Boolean只包含True與False。
let nameFieldChecked = true; // yes, name field is checked
let ageFieldChecked = false; // no, age field is not checked
也可以作為比較的結果:
let isGreater = 4 > 1;
console.log( isGreater ); // true
相較於其他語言,JavaScript中的null並不是對不存在的object的引用,JavaScript僅代表“無”“空”“未知”的特殊值。
和null一樣自成類型,undefined的含義是為被賦值,如果一個變數被聲明,但是並未賦值,那他就是undefined。
let age;
console.log(age); // undefined
從技術上來講,可以將undefined賦值給一個變數:
let age = 100;
// 主動將值改為 undefined
age = undefined;
alert(age); // "undefined"
但不建議這麼做,通常會將null賦值給變數,而undefined則保留作為變數初始的默任值。
symbol值表示唯一的識別符號,可以使用Symbol()來創建。
// id 是 symbol一個實例化的對象
let id = Symbol();
創建時也可以給Symbol一個描述(symbol名)
// id 是描述为 "id" 的 Symbol
let id = Symbol("id");
且symbol是保證唯一的:
let id1 = Symbol("id");
let id2 = Symbol("id");
alert(id1 == id2); // false
Symbol不會被自動轉換為字串
JavaScript大多都支持字符串的轉換,例如我們可以alert任何的值,都可以生效,但是symbol例外。
let id = Symbol("id");
alert(id); // 類型錯誤:無法將 Symbol 值轉換為字串。
這是一種防止混亂的語言保護,因為字符串跟symbol本質上不同,不應該轉換成為另一個。如果真的想要顯示出一個symbol:
let id = Symbol("id");
alert(id.toString()); // Symbol(id)
或者獲取symbol.description,只顯示出描述:
let id = Symbol("id");
alert(id.description); // id
我們可以透過Symbol創建object的隱藏屬性,從外部是無法獲取這些屬性。
let cart = {
userName: "John"
}
let id = Symbol("id");
cart[id] = 1;
console.log(cart[id])
使用Symbold("id")與使用字串"id"來新增主要的差別在於,如果cart是第三方的代碼,如果我們隨意新增屬性,是有可能影響到第三方的代碼,但是透過Symbol新增的屬性,第三方代碼中是獲取不到的。
另外,Symbol在for...in中是會被忽略的:
let id = Symbol("id")
let cart = {
userName:"John",
age:20,
[id]:1
};
for(let key in cart) {
console.log(key)
} // name, age
Object.keys()也一樣會忽略。但是Object.assign會複製symbol所創建的屬性:
let id = Symbol("id");
let person = {
height:180,
weight:70,
[id]:10
}
let clonePerson = Object.assign({}, person);
console.log(clonePerson[id]);
所有的Symbol的值都是不同的,即使他們的名稱一樣,如果說我們想要讓有相同名子的Symbol返回相同的值,可以使用Symbol.for。
Symbol.for(key)會從一個全域的Symbol註冊列表中搜尋有相同名稱的Symbol值,如果沒有就新增一個,並且放入全域註冊列表中。
let id = Symbol.for("id") // 不存在的話,就新增
let idA = Symbol.for("id"); // 獲取到id
console.log( id === idA); // true
還有另一個methodSymbol.keyFor是用來反查Symbol的名稱。
let idA = Symbol.for("userAId")
let idB = Symbol.for("userBId")
console.log(Symbol.keyFor(idA)) // userAId
console.log(Symbol.keyFor(idB)) // userBId
剩下的Object內容較多,明天再補充
參考資料: